﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TCP_Client
{
    class Data_Crc
    {

        /*RC16校验算法,（低字节在前，高字节在后）
               * 参数：数据缓冲区，缓冲区长度
               * 返回值:16位校验码
               */
        public UInt16 CRC_16(byte[] data, UInt16 datalen)
        {
            UInt16 cpoly = 0x1021;
            UInt16 cin = 0x0000;
            int wchar = 0;
            int i, j;
            if (data.Length == 0)
                throw new Exception("调用CRC16校验算法,（低字节在前，高字节在后）时发生异常，异常信息：被校验的数组长度为0。");

            for (i = 1; i < datalen; i++)
            {
                wchar = data[i];
                cin ^= (UInt16)(wchar << 8);
                for (j = 0; j < 8; j++)
                {
                    if ((cin & 0x8000) != 0)
                    {
                        cin = (UInt16)(cin << 0x0001);
                        cin = (UInt16)(cin ^ cpoly);
                    }
                    else
                        cin = (UInt16)(cin << 1);

                }

            }

            return cin;


        }
        /*校验数据
         * 参数：数据缓冲区，缓冲区长度
         * 返回值:1失败，0成功
         */
        public int check_data(byte[] buf, UInt16 len)
        {

            byte[] temp = new byte[120];
            int i;
            UInt16 index = 0;
            UInt16 pack_len;

            /*转义*/
            if ((buf[0] == 0x55) && (buf[len - 1] == 0x55))
            {
                for (i = 0; i < len; i++)
                {

                    temp[index++] = buf[i];

                }
            }
            else
            {
                return 1;
            }
            /*长度检测*/

            pack_len = temp[5];
            pack_len = (UInt16)((pack_len << 8) | (UInt16)temp[4]);
            pack_len = (UInt16)((pack_len << 16) | (UInt16)temp[3]);
            pack_len = (UInt16)((pack_len << 24) | (UInt16)temp[2]);
            //     i = temp[2];
            if (pack_len == (index - 4))
            {
                UInt16 crc = temp[index - 3];
                crc = (UInt16)((crc << 8) | (UInt16)temp[index - 2]);
                if (crc == 0xffff)
                {
                    return 0;    //test mode
                }
                else if (crc == CRC_16(temp, (UInt16)(index - 3)))
                {
                    return 0;
                }
                return 1;


            }
            return 1;

        }
        /*发送数据包
         * 参数:数据缓冲区，数据包长度，接收缓冲区
         * 返回值:接收区数据长度
         */
    }
}
